type cat = {
  run: () => void;
  name: string;
};

type dogg = {
  shark: () => void;
  name: string;
};

// 该函数是一个类型保护函数，
// 用于判断传入的参数animal是否是cat类型。
// 函数的参数animal的类型是cat或dog，
// 但通过animal is cat的语法，
// 可以将参数的类型缩小为cat。
// 函数内部通过判断animal是否具有run属性来确定其类型，如果存在run属性，则返回true，否则返回false。

// 类型保护函数
function isCat(animal: cat | dogg): animal is cat {
  return (animal as cat).run !== undefined; //判断传递的参数是否有run函数
}

// 实现函数
function getSmallPet(): cat | dogg {
  let cat: cat = {
    name: "狸花猫",
    run() {},
  };

  let dog: dogg = {
    name: "汪汪狗",
    shark() {},
  };

  return Math.random() > 0.5 ? cat : dog;
}

let pet = getSmallPet();
if (isCat(pet)) {
  pet.run();
} else {
  pet.shark();
}

const zoom: (cat | dogg)[] = [
  getSmallPet(),
  getSmallPet(),
  getSmallPet(),
  getSmallPet(),
];

const underWater: cat[] = zoom.filter(isCat);
console.log(underWater);
const underWater2: cat[] = zoom.filter(isCat) as cat[];

const underWater3: cat[] = zoom.filter(function (item): item is cat {
  if (isCat(item)) {
    return true;
  } else {
    return false;
  }
});
